
package com.hlkj.pay.controller.pay.huifu;

import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.stream.Collectors;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.alibaba.excel.context.AnalysisContext;
import com.alibaba.excel.event.AnalysisEventListener;
import com.hlkj.pay.infrastructure.model.pay.PayChannelDictDO;

/**
 * @author HlpayTeam
 * @date 2024/09/25 9:54
 */
public class HuifuCategoryDictListener extends AnalysisEventListener<HuifuCategory> {

    private static final Logger LOGGER = LoggerFactory.getLogger(HuifuCategory.class);

    /**
     * 每隔5条存储数据库，实际使用中可以3000条，然后清理list ，方便内存回收
     */
    private static final int BATCH_COUNT = 5;

    List<HuifuCategory> list = new LinkedList<>();

    private String channelCode;

    private String dictKey;

    /**
     * 假设这个是一个DAO，当然有业务逻辑这个也可以是一个service。当然如果不用存储这个对象没用。
     */

    public HuifuCategoryDictListener(String channelCode, String dictKey) {
        this.channelCode = channelCode;
        this.dictKey = dictKey;
    }

    /**
     * 这个每一条数据解析都会来调用
     *
     * @param data
     *            one row value. Is is same as
     *            {@link AnalysisContext#readRowHolder()}
     * @param context
     */
    @Override
    public void invoke(HuifuCategory data, AnalysisContext context) {
        // LOGGER.info("解析到一条数据:{}", JSON.toJSONString(data));
        list.add(data);
        // 达到BATCH_COUNT了，需要去存储一次数据库，防止数据几万条数据在内存，容易OOM
        if (list.size() >= BATCH_COUNT) {
            // processSql();
            // 存储完成清理 list
            // list.clear();
        }
    }

    /**
     * 所有数据解析完成了 都会来调用
     *
     * @param context
     */
    @Override
    public void doAfterAllAnalysed(AnalysisContext context) {
        // 这里也要保存数据，确保最后遗留的数据也存储到数据库
        LOGGER.info("所有数据解析完成！");
        processSql();
    }
    public void processSql() {
        // List<PayChannelDictDO> payChannelDictList = new ArrayList<>();
        Map<String, List<HuifuCategory>> oneCategory = list.stream().collect(Collectors.groupingBy(helibaoCategory -> helibaoCategory.getOneCategory()));
        AtomicInteger oneCode= new AtomicInteger(1);
        List<PayChannelDictDO> payChannelDictList = new LinkedList<>();
        oneCategory.forEach((one,twoList)->{
            String oneCodeValue=String.format("%02d", oneCode.get());
            PayChannelDictDO onePayChannelDictDO = new PayChannelDictDO();
            onePayChannelDictDO.setDictLevel(1);
            onePayChannelDictDO.setDictValue(oneCodeValue);
            onePayChannelDictDO.setDictDesc(twoList.get(0).getOneCategory());
            onePayChannelDictDO.setParentDictKey("");
            payChannelDictList.add(onePayChannelDictDO);

            Map<String, List<HuifuCategory>> twoCategory = twoList.stream().collect(Collectors.groupingBy(helibaoCategory -> helibaoCategory.getTwoCategory()));
            AtomicInteger twoCode= new AtomicInteger(1);
            twoCategory.forEach((two,thirdList)->{
                String twoCodeValue=String.format("%02d", twoCode.get());
                PayChannelDictDO twoPayChannelDictDO = new PayChannelDictDO();
                twoPayChannelDictDO.setDictLevel(2);
                twoPayChannelDictDO.setDictValue(oneCodeValue+twoCodeValue);
                twoPayChannelDictDO.setDictDesc(thirdList.get(0).getTwoCategory());
                twoPayChannelDictDO.setParentDictKey(onePayChannelDictDO.getDictValue());
                payChannelDictList.add(twoPayChannelDictDO);
                thirdList.stream().forEach(third->{
                    PayChannelDictDO thirdPayChannelDictDO = new PayChannelDictDO();
                    thirdPayChannelDictDO.setDictLevel(3);
                    thirdPayChannelDictDO.setDictValue(third.getCode());
                    thirdPayChannelDictDO.setDictDesc(third.getThirdCategory());
                    thirdPayChannelDictDO.setParentDictKey(twoPayChannelDictDO.getDictValue());
                    payChannelDictList.add(thirdPayChannelDictDO);
                });
                twoCode.set(twoCode.get() + 1);
            });
            oneCode.set(oneCode.get() + 1);

        });
        List<String> dictSql = new LinkedList<>();
        // System.out.println(entryL.getKey());
        // System.out.println("========================================");
        payChannelDictList.stream().forEach(payChannelDictDO -> {
            // 一级
            StringBuilder parentSb = new StringBuilder(
                    "insert into t_pay_channel_dict(channel_code,dict_key,parent_dict_key,dict_level,dict_value,dict_desc) value (");
            parentSb.append("'");
            parentSb.append(channelCode);
            parentSb.append("','");
            parentSb.append(dictKey);
            parentSb.append("','");
            parentSb.append(payChannelDictDO.getParentDictKey());
            parentSb.append("',");
            parentSb.append(payChannelDictDO.getDictLevel());
            parentSb.append(",'");
            parentSb.append(payChannelDictDO.getDictValue());
            parentSb.append("','");
            parentSb.append(payChannelDictDO.getDictDesc());
            parentSb.append("');");
            dictSql.add(parentSb.toString());

        });
        dictSql.stream().forEach(sql -> {
            System.out.println(sql);
        });
    }
}
